package KUtilities;

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;
import javax.swing.Timer;

public class KPanel extends JPanel{
	
	private static final long serialVersionUID = 1L;
    private Timer timer;
    private int fps;
    private float x,y,w,h;
    private Thread thread;
    private BufferedImage img;
    
    /**
     * New Panel with transistion effects
     */
    public KPanel(){
    	fps=40;
    	x=y=w=h=0;
    }
    
    /**
     * New Panel with transistion effects
     * @param visible visible initially or not
     */
    public KPanel(boolean visible){
    	setVisible(visible);
    	fps=40;
    	x=y=w=h=0;
    }
    
    /**
     * Zooms the panel in or out for the given time
     * @param type "in" or "out"
     * @param time time of the transition
     */
    private void zoom(final String type,int time){
    	final int width,height;
    	setVisible(true);
    	width=getWidth();
    	height=getHeight();
    	img=new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
    	super.paint(img.getGraphics());
    	if(type.toLowerCase().equals("in")){
			w=h=0;
			x=width/2;
			y=height/2;
		}else if(type.toLowerCase().equals("out")){
			w=width;
			h=height;
			x=y=0;
		}
    	final float noFrames=(int)(fps*((float)time/1000));
        ActionListener zoomAction=new ActionListener(){
            public void actionPerformed(ActionEvent ae){
            	if((type.equals("out")&&w>0&&h>0)||(type.equals("in")&&w<width&&h<height)){
            		if(type.toLowerCase().equals("in")){
            			w+=(float)width/noFrames;
            			h+=(float)height/noFrames;
            			x-=(float)width/noFrames/2;
            			y-=(float)height/noFrames/2;
            		}else if(type.toLowerCase().equals("out")){
            			w-=(float)width/noFrames;
            			h-=(float)height/noFrames;
            			x+=(float)width/noFrames/2;
            			y+=(float)height/noFrames/2;
            		}
                }else{
                	if(type.toLowerCase().equals("out"))
            			setVisible(false);
                    timer.stop();
                    img=null;
                    x=y=w=h=0;
                }
            	repaint();
            }
        };
    	int repeatTime=1000/fps;
        timer=new Timer(repeatTime,zoomAction);
        timer.start();
        thread=new Thread(){
        	public void run(){
        		while(timer.isRunning());
        	}
        };
        thread.start();
    }
    
    /**
     * Zooms in the panel in 500ms
     */
    public void zoomIn(){
    	zoom("in",500);
    }
    
    /**
     * Zooms in the panel in given time 
     * @param time time of transition in ms
     */
    public void zoomIn(int time){
    	zoom("in",time);
    }
    
    /**
     * Zooms out the panel in 500ms
     */
    public void zoomOut(){
    	zoom("out",500);
    }
    
    /**
     * Zooms out the panel in given time 
     * @param time time of transition in ms
     */
    public void zoomOut(int time){
    	zoom("out",time);
    }
    
    /**
     * Set new Frame Rate. Default is 40fps
     * @param fps new frame rate
     */
    public void setFPS(int fps){
    	this.fps=fps;
    }
    
    public void paint(Graphics g){
        if(img==null)
        	super.paint(g);
        else{
        	g.drawImage(img, (int)x, (int)y, (int)w, (int)h, KPanel.this);
        }
    }
    
    /**
     * Tests if this thread is alive.
     * A thread is alive if it has been started and has not yet died.
     * @return true if this thread is alive; false otherwise.
     */
	public boolean isAlive() {
		if(thread!=null)
			return thread.isAlive();
		else
			return false;
	}
}
